home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / misc1 / iv26_w30.zip / EXAMPLES / IDRAW / STATEVIE.C < prev    next >
C/C++ Source or Header  |  1980-01-05  |  12KB  |  417 lines

  1. /*
  2.  * Copyright (c) 1987, 1988, 1989 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Stanford not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Stanford makes no representations about
  11.  * the suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  20.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. // $Header: stateviews.c,v 1.13 89/10/09 14:49:54 linton Exp $
  24. // implements classes StateView and StateView's subclasses.
  25.  
  26. #include "ipaint.h"
  27. #include "istring.h"
  28. #include "sllines.h"
  29. #include "state.h"
  30. #include "stateviews.h"
  31. #include <InterViews/painter.h>
  32. #include <InterViews/perspective.h>
  33. #include <InterViews/shape.h>
  34. #include <stdio.h>
  35.  
  36. // StateView attaches itself to the State's list of views to update
  37. // and stores the State and text label.
  38.  
  39. StateView::StateView (State* s, const char* l) {
  40.     s->Attach(this);
  41.     state = s;
  42.     label = strdup(l ? l : "");
  43. }
  44.  
  45. // Free storage allocated for the text label.
  46.  
  47. StateView::~StateView () {
  48.     delete label;
  49. }
  50.  
  51. // Reconfig pads the view's shape to accomodate its text label.
  52. // Basing padding on the font in use ensures the padding will change
  53. // proportionally with changes in the font's size.
  54.  
  55. static const float WIDTHPAD = 1.0; // fraction of font->Width(EM)
  56. static const float HTPAD = 0.2;       // fraction of font->Height() 
  57. static const char* EM = "m";       // widest alphabetic character in any font
  58.  
  59. void StateView::Reconfig () {
  60.     Interactor::Reconfig();
  61.     Font* font = output->GetFont();
  62.     int xpad = round(WIDTHPAD * font->Width(EM));
  63.     int ypad = round(HTPAD * font->Height());
  64.     shape->width = font->Width(label) + (2 * xpad);
  65.     shape->height = font->Height() + (2 * ypad);
  66.     shape->Rigid(shape->width - xpad, 0, 2 * ypad, 0);
  67. }
  68.  
  69. // Redraw displays the text label.
  70.  
  71. void StateView::Redraw (Coord l, Coord b, Coord r, Coord t) {
  72.     output->ClearRect(canvas, l, b, r, t);
  73.     output->Text(canvas, label, label_x, label_y);
  74. }
  75.  
  76. // Resize centers the text label's position unless the label won't fit
  77. // on the canvas, in which case Resize left justifies the position.
  78.  
  79. void StateView::Resize () {
  80.     Font* font = output->GetFont();
  81.     label_x = max(0, (xmax - font->Width(label) + 1) / 2);
  82.     label_y = (ymax - font->Height() + 1) / 2;
  83. }
  84.  
  85. // BrushView creates a graphic to demonstrate the brush's effect on a
  86. // line.
  87.  
  88. static const int PICXMAX = 28;    // chosen to minimize scaling for canvas
  89. static const int PICYMAX = 18;
  90.  
  91. BrushView::BrushView (State* s) : (s, " N ") {
  92.     brushindic = new LineSelection(0, 0, PICXMAX, 0, state->GetGraphicGS());
  93.     brushindic->SetTransformer(nil);
  94. }
  95.  
  96. // Free storage allocated for the graphic.
  97.  
  98. BrushView::~BrushView () {
  99.     delete brushindic;
  100. }
  101.  
  102. // Skew comments/code ratio to work around cpp bug
  103. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  104.  
  105. // Update updates the view if any of the brush, colors, or pattern
  106. // changes.
  107.  
  108. void BrushView::Update () {
  109.     IBrush* brush = state->GetBrush();
  110.     IColor* fgcolor = state->GetFgColor();
  111.     IColor* bgcolor = state->GetBgColor();
  112.     IPattern* pattern = state->GetPattern();
  113.     if (brushindic->GetBrush() != brush ||
  114.     brushindic->GetFgColor() != fgcolor ||
  115.     brushindic->GetBgColor() != bgcolor ||
  116.     brushindic->GetPattern() != pattern)
  117.     {
  118.     brushindic->SetBrush(brush);
  119.     brushindic->SetColors(fgcolor, bgcolor);
  120.     brushindic->SetPattern(pattern);
  121.     Draw();
  122.     }
  123. }
  124.  
  125. // Reconfig computes BrushView's shape and makes room for the VBorder
  126. // between itself and the PatternView.
  127.  
  128. void BrushView::Reconfig () {
  129.     StateView::Reconfig();
  130.     shape->width -= 1;
  131.     shape->Rigid();
  132. }
  133.  
  134. // Redraw displays the text label if the brush's the none brush, else
  135. // it displays the graphic to demonstrate the brush's effect.
  136.  
  137. void BrushView::Redraw (Coord l, Coord b, Coord r, Coord t) {
  138.     IBrush* brush = (IBrush*) brushindic->GetBrush();
  139.     if (brush->None()) {
  140.     StateView::Redraw(l, b, r, t);
  141.     } else {
  142.     output->ClearRect(canvas, l, b, r, t);
  143.     brushindic->Draw(canvas);
  144.     }
  145. }
  146.  
  147. // Resize scales the graphic to fit the canvas' size.
  148.  
  149. void BrushView::Resize () {
  150.     StateView::Resize();
  151.     float xmag = float(xmax) / PICXMAX;
  152.     float hy = float(ymax) / 2;
  153.     brushindic->SetTransformer(nil);
  154.     brushindic->Scale(xmag, 1.);
  155.     brushindic->Translate(0., hy);
  156. }
  157.  
  158. // DrawingNameView just passes the drawing's name to StateView.
  159.  
  160. DrawingNameView::DrawingNameView (State* s) : (s, GetDrawingName(s)) {
  161. }
  162.  
  163. // Update updates the view of the drawing's name.
  164.  
  165. void DrawingNameView::Update () {
  166.     const char* drawingname = GetDrawingName(state);
  167.     if (strcmp(drawingname, label) != 0) {
  168.     delete label;
  169.     label = strdup(drawingname);
  170.     Resize();
  171.     Draw();
  172.     }
  173. }
  174.  
  175. // Reconfig gives DrawingNameView's shape some stretchability to get
  176. // more space if the HBox has room for it to stretch.
  177.  
  178. void DrawingNameView::Reconfig () {
  179.     StateView::Reconfig();
  180.     shape->hstretch = hfil;
  181. }
  182.  
  183. // Resize left justifies the text label's position.
  184.  
  185. void DrawingNameView::Resize () {
  186.     Font* font = output->GetFont();
  187.     label_x = 0;
  188.     label_y = (ymax - font->Height() + 1) / 2;
  189. }
  190.  
  191. // GetDrawingName returns the drawing's name or a default label if it
  192. // has no name.
  193.  
  194. const char* DrawingNameView::GetDrawingName (State* state) {
  195.     const char* drawingname = state->GetDrawingName();
  196.     return drawingname ? drawingname : "[unnamed drawing]";
  197. }
  198.  
  199. // FontView passes the font's print name and size to StateView for its
  200. // label.
  201.  
  202. FontView::FontView (State* s) : (s, GetPrintFontAndSize(s)) {
  203.     background = nil;
  204. }
  205.  
  206. // Free storage allocated for the background painter.
  207.  
  208. FontView::~FontView () {
  209.     Unref(background);
  210. }
  211.  
  212. // Update updates the view if the label or the current color changes.
  213.  
  214. void FontView::Update () {
  215.     const char* name = GetPrintFontAndSize(state);
  216.     Color* fgcolor = *state->GetFgColor();
  217.     if (strcmp(name, label) != 0) {
  218.     delete label;
  219.     label = strdup(name);
  220.     output->SetColors(fgcolor, output->GetBgColor());
  221.     Resize();
  222.     Draw();
  223.     } else if (output->GetFgColor() != fgcolor) {
  224.     output->SetColors(fgcolor, output->GetBgColor());
  225.     Draw();
  226.     }
  227. }
  228.  
  229. // Reconfig gives FontView's shape some stretchability to get more
  230. // space if the HBox has room for it to stretch, creates a new painter
  231. // to draw a gray background behind the label, and replaces output
  232. // with a new painter to use a different color.
  233.  
  234. void FontView::Reconfig () {
  235.     StateView::Reconfig();
  236.     shape->hstretch = hfil;
  237.  
  238.     if (background == nil) {
  239.     background = new Painter(output);
  240.     background->Reference();
  241.     background->SetPattern(gray);
  242.     }
  243.  
  244.     Color* fgcolor = *state->GetFgColor();
  245.     Painter* copy = new Painter(output);
  246.     copy->Reference();
  247.     Unref(output);
  248.     output = copy;
  249.     output->SetColors(fgcolor, output->GetBgColor());
  250.     output->FillBg(false);
  251. }
  252.  
  253. // Redraw displays the graphic label over a gray background to make
  254. // the label visible even if it uses the white color.
  255.  
  256. void FontView::Redraw (Coord l, Coord b, Coord r, Coord t) {
  257.     background->FillRect(canvas, l, b, r, t);
  258.     output->Text(canvas, label, label_x, label_y);
  259. }
  260.  
  261. // GetPrintFontAndSize returns the font's print name and size.
  262.  
  263. const char* FontView::GetPrintFontAndSize (State* state) {
  264.     IFont* f = state->GetFont();
  265.     return f->GetPrintFontAndSize();
  266. }
  267.  
  268. // GriddingView passes the grid's gridding on/off status to StateView.
  269.  
  270. GriddingView::GriddingView (State* s) : (s, GetGridding(s)) {
  271. }
  272.  
  273. // Update updates the view of the grid's gridding on/off status.
  274.  
  275. void GriddingView::Update () {
  276.     const char* gridding = GetGridding(state);
  277.     if (strcmp(gridding, label) != 0) {
  278.     delete label;
  279.     label = strdup(gridding);
  280.     Draw();
  281.     }
  282. }
  283.  
  284. // GetGridding returns the status of the grid's gridding as a text
  285. // string.
  286.  
  287. const char* GriddingView::GetGridding (State* state) {
  288.     const char* gravity = nil;
  289.     if (state->GetGridGravity()) {
  290.     gravity = "gridding on";
  291.     } else {
  292.     gravity = "           ";
  293.     }
  294.     return gravity;
  295. }
  296.  
  297. // MagnifView attaches itself to the DrawingView's perspective to get
  298. // itself updated whenever the magnification changes.
  299.  
  300. MagnifView::MagnifView (State* s, Interactor* dwgview) : (s, GetMagnif(s)) {
  301.     dwgview->GetPerspective()->Attach(this);
  302. }
  303.  
  304. // Update updates the view of the current magnification.
  305.  
  306. void MagnifView::Update () {
  307.     const char* magnif = GetMagnif(state);
  308.     if (strcmp(magnif, label) != 0) {
  309.     delete label;
  310.     label = strdup(magnif);
  311.     Resize();
  312.     Draw();
  313.     }
  314. }
  315.  
  316. // Resize right justifies the text label's position.
  317.  
  318. void MagnifView::Resize () {
  319.     Font* font = output->GetFont();
  320.     label_x = xmax - font->Width(label) + 1;
  321.     label_y = (ymax - font->Height() + 1) / 2;
  322. }
  323.  
  324. // GetMagnif returns the drawing's magnification as a text string.
  325.  
  326. const char* MagnifView::GetMagnif (State* state) {
  327.     static char mag[20];
  328.  
  329.     float magnif = state->GetMagnif();
  330.     sprintf(mag, "  mag %.10gx ", magnif);
  331.     return mag;
  332. }
  333.  
  334. // ModifStatusView just passes the modification status to StateView.
  335.  
  336. ModifStatusView::ModifStatusView (State* s) : (s, GetModifStatus(s)) {
  337. }
  338.  
  339. // Update updates the view of the current modification status.
  340.  
  341. void ModifStatusView::Update () {
  342.     const char* modifstatus = GetModifStatus(state);
  343.     if (strcmp(modifstatus, label) != 0) {
  344.     delete label;
  345.     label = strdup(modifstatus);
  346.     Draw();
  347.     }
  348. }
  349.  
  350. // GetModifStatus returns the drawing's modification status.
  351.  
  352. const char* ModifStatusView::GetModifStatus (State* state) {
  353.     switch (state->GetModifStatus()) {
  354.     case ReadOnly:
  355.     return "%";
  356.     case Unmodified:
  357.     return " ";
  358.     default:
  359.     return "*";
  360.     }
  361. }
  362.  
  363. // PatternView passes its none pattern label to StateView.
  364.  
  365. PatternView::PatternView (State* s) : (s, " N ") {
  366.     patindic = nil;
  367. }
  368.  
  369. // Free storage allocated for the fillrect painter.
  370.  
  371. PatternView::~PatternView () {
  372.     Unref(patindic);
  373. }
  374.  
  375. // Update updates the view if any of the colors or pattern changes.
  376.  
  377. void PatternView::Update () {
  378.     Color* fgcolor = *state->GetFgColor();
  379.     Color* bgcolor = *state->GetBgColor();
  380.     Pattern* pattern = *state->GetPattern();
  381.     if (patindic->GetFgColor() != fgcolor ||
  382.     patindic->GetBgColor() != bgcolor ||
  383.     patindic->GetPattern() != pattern)
  384.     {
  385.     patindic->SetColors(fgcolor, bgcolor);
  386.     patindic->SetPattern(pattern);
  387.     Draw();
  388.     }
  389. }
  390.  
  391. // Reconfig creates the pattern indicator's painter.
  392.  
  393. void PatternView::Reconfig () {
  394.     StateView::Reconfig();
  395.     shape->Rigid();
  396.     if (patindic == nil) {
  397.     Color* fgcolor = *state->GetFgColor();
  398.     Color* bgcolor = *state->GetBgColor();
  399.     Pattern* pattern = *state->GetPattern();
  400.     patindic = new Painter(output);
  401.     patindic->Reference();
  402.     patindic->SetColors(fgcolor, bgcolor);
  403.     patindic->SetPattern(pattern);
  404.     }
  405. }
  406.  
  407. // Redraw displays the text label if the pattern's the none pattern,
  408. // else it displays the fillrect to demonstrate the pattern's effect.
  409.  
  410. void PatternView::Redraw (Coord l, Coord b, Coord r, Coord t) {
  411.     if (state->GetPattern()->None()) {
  412.     StateView::Redraw(l, b, r, t);
  413.     } else {
  414.     patindic->FillRect(canvas, l, b, r, t);
  415.     }
  416. }
  417.